KPMP 6426 update vulns#62
Conversation
WalkthroughThis PR upgrades Spring Boot from 3.2.2 to 4.0.6, Gradle from 8.5 to 8.14, and modernizes Docker image building to use Spring Boot's native bootBuildImage task instead of Palantir's docker plugin. The application's GraphQL Query resolver is refactored to use Spring GraphQL's ChangesSpring Boot 4.0 and Spring GraphQL Migration
🚥 Pre-merge checks | ✅ 2✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: ffda1e6d-c7c3-4131-8cf6-ac16f9230cc2
📒 Files selected for processing (5)
.github/workflows/build-gradle-project.ymlDockerfilebuild.gradlegradle/wrapper/gradle-wrapper.propertiessrc/main/java/org/kpmp/Query.java
| - name: Push to Docker Hub if branch is develop | ||
| if: steps.branch-names.outputs.current_branch == 'develop' | ||
| run: | | ||
| docker push "kingstonduo/hydra-data:$IMAGE_TAG" | ||
| docker push "kingstonduo/hydra-data:${{env.IMAGE_TAG}}" | ||
|
|
||
| - name: Push to Docker Hub if branch is not develop | ||
| if: ${{ !steps.branch-names.outputs.current_branch == 'develop' }} | ||
| if: steps.branch-names.outputs.current_branch != 'develop' | ||
| run: | | ||
| docker push "kingstonduo/hydra-data:${{ steps.branch-names.outputs.current_branch }}" |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Inspect getCurrentGitBranch() and verify whether the workflow sets up an attached branch before bootBuildImage runs.
rg -nP -C2 'getCurrentGitBranch|rev-parse|bootBuildImage' build.gradle
rg -nP -C2 'checkout|branch' .github/workflows/build-gradle-project.ymlRepository: KPMP/hydra-data
Length of output: 1699
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Inspect workflow triggers and checkout configuration
sed -n '1,120p' .github/workflows/build-gradle-project.yml | nl -ba
echo "---- checkout block ----"
rg -n "uses: actions/checkout@v3" -n .github/workflows/build-gradle-project.yml -n
# Print 30 lines around checkout to see if it has inputs like ref/fetch-depth
python3 - <<'PY'
import itertools, re, pathlib
p = pathlib.Path(".github/workflows/build-gradle-project.yml")
lines = p.read_text().splitlines()
for i,l in enumerate(lines):
if "uses: actions/checkout@v3" in l:
start=max(0,i-15); end=min(len(lines), i+25)
for j in range(start,end):
print(f"{j+1:4d}:{lines[j]}")
break
PY
echo "---- get/usage of IMAGE_TAG ----"
rg -n "IMAGE_TAG" .github/workflows/build-gradle-project.ymlRepository: KPMP/hydra-data
Length of output: 102
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "---- workflow header (first 120 lines) ----"
sed -n '1,120p' .github/workflows/build-gradle-project.yml | cat -n
echo "---- find triggers ----"
rg -n "^(on:|name:|jobs:)" .github/workflows/build-gradle-project.yml -n
echo "---- checkout block with context ----"
python3 - <<'PY'
from pathlib import Path
p = Path(".github/workflows/build-gradle-project.yml")
lines = p.read_text().splitlines()
for i,l in enumerate(lines):
if "uses: actions/checkout@v3" in l:
start=max(0,i-15); end=min(len(lines), i+35)
for j in range(start,end):
print(f"{j+1:4d}:{lines[j]}")
break
PY
echo "---- checkout 'with' keys (if any) ----"
rg -n "with:|ref:|fetch-depth:" .github/workflows/build-gradle-project.ymlRepository: KPMP/hydra-data
Length of output: 3929
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Show full getCurrentGitBranch and bootBuildImage section
rg -n "def getCurrentGitBranch\\(\\)|bootBuildImage\\s*\\{" build.gradle
python3 - <<'PY'
from pathlib import Path
p = Path("build.gradle")
lines = p.read_text().splitlines()
# print around getCurrentGitBranch
for i,l in enumerate(lines):
if "def getCurrentGitBranch" in l:
start=max(0,i-5); end=min(len(lines), i+60)
for j in range(start,end):
print(f"{j+1:4d}:{lines[j]}")
break
PYRepository: KPMP/hydra-data
Length of output: 1195
🌐 Web query:
actions/checkout v3 detached HEAD default behavior push event rev-parse --abbrev-ref HEAD
💡 Result:
In GitHub Actions, with actions/checkout v3, when the workflow is triggered by a push and you do not explicitly set ref, the action checks out the commit for the event in detached HEAD mode (so git rev-parse --abbrev-ref HEAD prints HEAD, not a branch name). This detached-head behavior is because the action checks out a specific commit/ref rather than creating/checking out a local branch by default.[1][2] What git rev-parse --abbrev-ref HEAD returns: - In detached HEAD state, --abbrev-ref cannot resolve a “current branch” symbolic ref, so it outputs HEAD (i.e., the name of the commit-ish you’re on).[1][3] How to get the branch name for a push event (recommended): - Use GitHub context variables rather than parsing git metadata. For example, for push workflows you can use GITHUB_REF_NAME (or GITHUB_REF) to get the branch/ref that triggered the workflow. (This avoids relying on the detached-HEAD checkout that actions/checkout performs.)[2] If you truly need a local branch in the runner: - You can create/switch to a branch after checkout (e.g., using git switch -c <name>), but note this is a separate step and doesn’t change that checkout itself happens detached.[2] Notes on other checkout-related defaults (unrelated to the detached HEAD behavior): - actions/checkout fetches only a single commit by default (unless you set fetch-depth). It documents fetch-depth and that 0 means fetch all history.[4][5]
Citations:
- 1: https://stackoverflow.com/questions/47098342/jenkinsfile-git-rev-parse-abbrev-ref-head-returns-head
- 2: Detached HEAD State actions/checkout#6
- 3: https://git.github.io/htmldocs/git-rev-parse.html
- 4: https://github.com/actions/checkout/tree/40a16ebeed7da831425b665e600750cb36b38d06
- 5: https://github.com/marketplace/actions/checkout?version=v3.6.0
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Check for version definition(s)
rg -n "^[[:space:]]*version[[:space:]]*=|project\\.version\\b|version\\s+['\"]" build.gradle gradle.properties **/gradle.properties || true
# If build.gradle is big, also show the top 120 lines
sed -n '1,140p' build.gradle | cat -nRepository: KPMP/hydra-data
Length of output: 3100
Critical: Docker push tag likely mismatches Gradle-built image tag (detached HEAD).
bootBuildImage tags the image as kingstonduo/hydra-data: + getCurrentGitBranch(), and getCurrentGitBranch() runs git rev-parse --abbrev-ref HEAD. With actions/checkout@v3 (no ref:) on on: push, the checkout is in detached-HEAD by default, so rev-parse --abbrev-ref HEAD returns HEAD and the built image tag becomes kingstonduo/hydra-data:HEAD (not the branch name).
As a result, both Docker Hub push steps can fail: the develop step pushes ...:${{ env.IMAGE_TAG }} (1.12.0) and the non-develop step pushes ...:${{ steps.branch-names.outputs.current_branch }} (e.g., feature/...)—neither matches ...:HEAD.
🧰 Tools
🪛 zizmor (1.25.2)
[info] 49-49: code injection via template expansion (template-injection): may expand into attacker-controllable code
(template-injection)
| // Docker image building is now handled by Spring Boot's bootBuildImage task | ||
| // Usage: ./gradlew bootBuildImage |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win
Stale Dockerfile left behind after migrating to bootBuildImage.
bootBuildImage produces an OCI image via Paketo buildpacks and does not use the repo's Dockerfile at all. The unpack task that populated target/dependency (which the existing Dockerfile COPYs from) has also been removed, so the Dockerfile is now both unused by the build pipeline and broken as a standalone build. Recommend deleting Dockerfile as part of this PR, or adding a comment in it stating it is no longer in use, to avoid future confusion.
| @@ -1,4 +1,4 @@ | |||
| FROM alpine:3.19.1 | |||
| FROM alpine:3.22.4 | |||
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win
Dockerfile is now orphaned by the migration.
With the move to ./gradlew bootBuildImage (Paketo buildpacks) and the removal of the unpack task, nothing in the build now produces target/dependency/BOOT-INF/..., so this Dockerfile can no longer be built successfully. Bumping the base image to alpine:3.22.4 updates a file that is effectively dead code. Suggest removing the Dockerfile (and skipping the alpine bump altogether) unless it is still intended to support a separate, documented workflow.
Note: the Trivy "USER should not be root" finding is moot if the file is removed; if you choose to keep the Dockerfile, it should be addressed by adding a non-root USER directive before ENTRYPOINT.
🧰 Tools
🪛 Trivy (0.69.3)
[error] 1-1: Image user should not be 'root'
Specify at least 1 USER command in Dockerfile with non-root user as argument
Rule: DS-0002
(IaC/Dockerfile)
Summary by CodeRabbit